//
//  SocketEngine.m
//  HelloWorld
//
//  Created by wuyifan on 11-6-22.
//  Copyright 2011 home. All rights reserved.
//

#import "SocketEngine.h"

@implementation SocketEngine

- (id)init
{
	[super init];
	m_socket = [[AsyncSocket alloc] initWithDelegate:self];
	m_listener = nil;
	m_isConnected = NO;
	return self;
}

-(void)dealloc
{
	[m_socket release];
	[super dealloc];
}

- (BOOL)connect: (NSString *) hostIP port:(int) hostPort
{
	if(m_isConnected) return NO;
	
	NSError *err = nil;  
	BOOL res = [m_socket connectToHost:hostIP onPort:hostPort error:&err];
	return res;
}

- (void)close
{
	if(m_isConnected)
	{
		[m_socket disconnect];
	}
}

- (void)setEventListener: (EventListener*) listener
{
	m_listener = listener;
}

- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
	m_recvLen = 0;
	m_procLen = 0;
	m_readLen = 0;
	m_sendLen = 0;
	m_isConnected = YES;
	
	[m_socket readDataWithTimeout:-1 buffer:nil bufferOffset:0 maxLength:BUFFERSIZE tag:0];
	
	[m_listener OnConncet:self];
}

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
	[m_listener OnDisconncet:self];
}

- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
	m_isConnected = NO;
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
	size_t len = [data length];
	const void* dat = [data bytes];
	memcpy(m_recvBuff+m_recvLen, dat, len);
	m_recvLen += len;
	
	while(true)
	{
		size_t leftLen = m_recvLen - m_procLen;
		
		if(leftLen<sizeof(MessageHeader)) break;
		
		MessageHeader* header = (MessageHeader*)(m_recvBuff + m_procLen);
		size_t msglen = header->msgLen;
		if(header->msgVer!=MSGVERSION || msglen<=0 || msglen>BUFFERSIZE)
		{
			//消息不合法
			m_recvLen = m_procLen = 0;
			break;
		}
		
		if(leftLen<msglen) break;
		
		m_readLen = m_procLen + sizeof(MessageHeader);
		m_procLen += msglen;
		[m_listener OnRecv:self cmdId:header->cmdId msgLen:msglen-sizeof(MessageHeader)];
	}
	
	size_t leftLen = m_recvLen - m_procLen;
	if(leftLen>0) memmove(m_recvBuff,m_recvBuff+m_procLen,leftLen);
	m_recvLen = leftLen;
	m_procLen = 0;
	[m_socket readDataWithTimeout:-1 buffer:nil bufferOffset:0 maxLength:BUFFERSIZE-leftLen tag:0];
}

- (int)ReadInt
{
	int res = *(int*)(m_recvBuff+m_readLen);
	m_readLen += sizeof(int);
	return res;
}

- (void*) ReadData: (size_t) size
{
	void* res = (void*)(m_recvBuff+m_readLen);
	m_readLen += size;
	return res;
}
//- (void*) ReadMutableData:(size_t) size{
//	[self ReadInt];
//	void* res = (void*)(m_recvBuff+m_readLen);
//	m_readLen += size;
//	return res;
//}

- (void) NewMessage: (int) cmdId
{
	m_msgHeader = (MessageHeader*)(m_sendBuff+m_sendLen);
	m_sendLen += sizeof(MessageHeader);
	m_msgHeader->msgVer = MSGVERSION;
	m_msgHeader->msgLen = sizeof(MessageHeader);
	m_msgHeader->cmdId = cmdId;
}

- (void) WriteInt: (int) data
{
	*(int*)(m_sendBuff+m_sendLen) = data;
	m_sendLen += sizeof(int);
	m_msgHeader->msgLen += sizeof(int);
}

- (void*) WriteNonData: (size_t) size
{
	void* res = (void*)(m_sendBuff+m_sendLen);
	m_sendLen += size;
	m_msgHeader->msgLen += size;
	return res;
}

- (void) WriteData: (NSData *)data
{
	void* res = (void*)(m_sendBuff+m_sendLen);
	
	if ([data length] > BUFFERSIZE - m_sendLen) {
		NSLog(@"SenBuffer Not Enough");
		return;
	}
	
	memcpy(res,[data bytes],[data length]);
	m_sendLen += [data length];
	m_msgHeader->msgLen += [data length];
}

- (void) Send;
{
	NSData* data = [NSData dataWithBytes:m_sendBuff length:m_sendLen];
	[m_socket writeData:data withTimeout:-1 tag:0];
	m_sendLen = 0;
}

@end
